#ifndef __M_ROUTE_H__
#define __M_ROUTE_H__

#include "../mqcommon//message.pb.h"
#include "../mqcommon/spliter.hpp"
#include "../mqcommon/logger.hpp"
#include <iostream>
#include <vector>

namespace zhong
{
    class Router
    {
    public:
        static bool isLegalRoutingKey(const std::string &routing_key)
        {
            for (auto &ch : routing_key)
            {
                // 1.判断传入的字符都是合法字符
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    (ch == '_' || ch == '.'))
                {
                    continue;
                }
                return false;
            }
            return true;
        }
        static bool isLegalBindingKey(const std::string &binding_key)
        {
            for (auto &ch : binding_key)
            {
                // 1.判断传入的字符都是合法字符
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    (ch == '_' || ch == '.') ||
                    (ch == '#' || ch == '*'))
                {
                    continue;
                }
                return false;
            }
            // 2.判断字符搭配规则合法
            std::vector<std::string> sub_words;
            Spliter::split(binding_key, ".", sub_words);
            for (auto &word : sub_words)
            {
                if (word.size() > 1 && (word.find("#") != std::string::npos || word.find("*") != std::string::npos))
                {
                    // 如果某一段的长度大于1，并且拥有 * 或者 # 不符合规则
                    return false;
                }
            }
            for (size_t i = 0; i < sub_words.size(); i++)
            {
                // 规则 # 两边不允许有 # 和 *
                if (sub_words[i] == "#" && sub_words[i - 1] == "*") // #前不能有*
                {
                    return false;
                }
                if (sub_words[i] == "*" && sub_words[i - 1] == "#") // #后不能有*
                {
                    return false;
                }
                if (sub_words[i] == "#" && sub_words[i - 1] == "#") // #前不能有#
                {
                    return false;
                }
            }

            return true;
        }
        static bool route(zhong::ExchangeType type, const std::string &routing_key, const std::string &binding_key)
        {
            if (type == zhong::ExchangeType::DIRECT) // 直接路由
            {
                return (routing_key == binding_key);
            }
            else if (type == zhong::ExchangeType::FANOUT) // 进行广播
            {
                return true;
            }
            else if (type == zhong::ExchangeType::TOPIC) // 进行主题交换
            {
                return routeTopic(routing_key, binding_key);
            }
            else
            {
                return false;
            }
        }

    private:
        static bool routeTopic(const std::string &routing_key, const std::string &binding_key)
        {
            std::vector<std::string> sub_binding_words;
            size_t num_binding = Spliter::split(binding_key, ".", sub_binding_words);
            std::vector<std::string> sub_routing_words;
            size_t num_routing = Spliter::split(routing_key, ".", sub_routing_words);

            // 构建二维数组，均初始化为0
            std::vector<std::vector<bool>> dp(num_binding + 1, std::vector<bool>(num_routing + 1, false));
            // 起始位置初始化为1
            dp[0][0] = true;
            
            // 如果sub_binding_words[0] == # 所在行头置为true
            // for (size_t i = 1; i < num_binding + 1; i++)
            // {
            //     // 为什么要 i - 1 因为对于二维数组我们额外开辟了一行一列
            //     // 但是对于两个字符串的vector，仍然是原样
            //     if (sub_binding_words[i - 1] == "#")
            //     {
            //         DEBUG_LOG("此时i = [%d]", i);
            //         dp[i][0] = true;
            //         continue;
            //     }
            //     break; 
            // }

            // 替代105 - 117
            // 如果sub_binding_words[0] == # 所在行头置为true
            if(sub_binding_words[0] == "#")
            {
                dp[1][0] = true;
            }

            for (size_t i = 1; i < num_binding + 1; i++)
            {
                for (size_t j = 1; j < num_routing + 1; j++)
                {
                    // 1.如果是* 或者两个单词相等，直接继承上一个
                    if (sub_binding_words[i - 1] == sub_routing_words[j - 1] || sub_binding_words[i - 1] == "*")
                    {
                        // 注意为什么这里是sub_binding_words[i-1]对应dp[i]
                        // 因为dp的i本质上多了1，相应的sub_binding_words，需要-1
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                    else if (sub_binding_words[i - 1] == "#")
                    {
                        dp[i][j] = dp[i - 1][j - 1] | dp[i][j - 1] | dp[i - 1][j];
                    }
                }
            }
            return dp[num_binding][num_routing];  
        }
    };
}


#endif